<template>
  <div class="validate-input-container pb-3">
    <input
      class="form-control"
      :class="{'is-invalid': inputRef.error}"
      :value="inputRef.val"
      @blur="validateInput"
      @input="updateValue"
      v-bind="$attrs"
    >
    <span v-if="inputRef.error" class="invalid-feedback">{{inputRef.message}}</span>
  </div>
</template>

<script lang='ts'>
import { defineComponent, onMounted, PropType, reactive } from 'vue'
import { emitter } from './ValidateForm.vue'
const emailReg = /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/

interface lengthProp{
  message:string,
  length:number
}
interface ruleProp{
  type:'required'|'email'|'range',
  message?:string,
  min?:lengthProp,
  max?:lengthProp
}
export type rulesProps=ruleProp[]

export default defineComponent({
  name: 'ValidateInput',
  // 从父组件中传入的验证规则
  props: {
    rules: Array as PropType<rulesProps>, // 使用as确定类型
    modelValue: String // 需要有一个modleValue属性，使得input支持v-model的秘诀：modelValue-->emit（'update:modelValue',xxxval）
  },
  inheritAttrs: false, // 不希望组件的根元素继承 attribute,设置成false!!!
  setup (props, context) {
    const inputRef = reactive({
      val: props.modelValue || '',
      error: false,
      message: ''
    })
    // 更新绑定值
    const updateValue = (e:KeyboardEvent) => {
      const targetValue = (e.target as HTMLInputElement).value
      inputRef.val = targetValue
      context.emit('update:modelValue', targetValue)
    }
    // 拿到验证结果值
    const validateInput = () => {
      if (props.rules) {
        // 判断是否所有的规则都通过校验
        const allPassed = props.rules.every(rule => {
          let passed = true
          inputRef.message = rule.message || ''
          switch (rule.type) {
            case 'required':
              passed = (inputRef.val.trim() !== '')
              break
            case 'email':
              passed = emailReg.test(inputRef.val)
              break
            case 'range':
              if (rule.min && inputRef.val.trim().length < rule.min.length) {
                passed = false
                inputRef.message = rule.min.message
              }
              if (rule.max && inputRef.val.trim().length > rule.max.length) {
                passed = false
                inputRef.message = rule.max.message
              }
              break
            default:
              break
          }
          return passed
        })
        inputRef.error = !allPassed
        return allPassed
      } else {
        return true
      }
    }
    // 如果验证错误，清空输入框
    const clearVal = () => {
      inputRef.val = ''
      // inputRef.error = false
      // inputRef.message = ''
    }
    onMounted(() => {
      emitter.emit('form-item-created', validateInput)
      emitter.emit('form-item-reset', clearVal)
    })
    return {
      inputRef,
      validateInput,
      updateValue,
      clearVal
    }
  }

})
</script>
